package util

import (
	"crypto/sha256"
	"encoding/base64"
	"errors"
	"fmt"
	"math/rand"
	"strings"

	pbkdf2 "golang.org/x/crypto/pbkdf2"
)

func PasswordEncode(password string, salt string, iterations int) (string, error) {
	// 一共三个参数，分别是原始密码、盐、迭代次数

	// 如果没有设置盐，则使用12位的随机字符串
	if strings.TrimSpace(salt) == "" {
		salt = CreateRandomString(16)
	}

	// 确保盐不包含美元$符号
	if strings.Contains(salt, "$") {
		return "", errors.New("salt contains dollar sign ($)")
	}

	// 如果迭代次数小于等于0，则设置为180000
	if iterations <= 0 {
		iterations = 180000
	}

	// pbkdf2加密 <--- 关键
	hash := pbkdf2.Key([]byte(password), []byte(salt), iterations, sha256.Size, sha256.New)
	// base64编码成为固定长度的字符串
	b64Hash := base64.StdEncoding.EncodeToString(hash)
	// 最终字符串拼接成pbkdf2_sha256密钥格式
	// return fmt.Sprintf("%s$%d$%s$%s", "pbkdf2_sha256", iterations, salt, b64Hash), nil
	return fmt.Sprintf("%s$%d$%s$%s", "PBKDF2$sha256", iterations, salt, b64Hash), nil
}

// 随机字符串生成函数（不深入讨论）
func CreateRandomString(len int) string {
	var container string
	var str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
	for i := 0; i < len; i++ {
		randomInt := rand.Intn(58)
		container += string(str[randomInt])
	}
	return container
}

// func main() {
// 	// fmt.Printf("%v", CreateRandomString(16))
// 	// password string, salt string, iterations int
// 	pw, _ := PasswordEncode("123456", "", 901)
// 	fmt.Printf("密码:%v", pw)
// 	// PBKDF2$sha256$901$VkfetLkj60UIaLLn$C9Wb0yRYhbE/ur1EC3OKOivCnJIKdnOY
// 	// PBKDF2$sha256$901$4JDPNQPmOmAHkpyE$7ATdb9gEK7pzRHfWgeqcCIcF25vm+qMuN6EqqsMEsRk=
// }
